glBindRenderbufferEXT (GL_RENDERBUFFER_EXT, source);
glFramebufferRenderbufferEXT (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
GL_RENDERBUFFER_EXT, source);
- glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0);
+ glBindFramebufferEXT (GL_DRAW_FRAMEBUFFER_EXT, 0);
}
else if (source_type == GL_TEXTURE)
{
+ glBindTexture (GL_TEXTURE_2D, source);
+
glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_ALPHA_SIZE, &alpha_size);
- glBindTexture (GL_TEXTURE_2D, source);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
- GL_TEXTURE_2D, source, 0);
- glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0);
+ glBindFramebufferEXT (GL_DRAW_FRAMEBUFFER_EXT, 0);
}
else
{
/* Translate to impl coords */
cairo_region_translate (clip_region, dx, dy);
- glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &texture_width);
- glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &texture_height);
-
if (alpha_size != 0)
{
cairo_region_t *opaque_region, *blend_region;
cairo_region_destroy (opaque_region);
cairo_region_destroy (blend_region);
}
+
+ glBindTexture (GL_TEXTURE_2D, source);
+
+ glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &texture_width);
+ glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &texture_height);
+
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
+ GL_TEXTURE_2D, source, 0);
+
glEnable (GL_SCISSOR_TEST);
glEnable (GL_TEXTURE_2D);
unsigned int texture_id;
int window_scale;
double sx, sy;
+ float umax, vmax;
+ gboolean use_texture_rectangle;
+ guint target;
current = gdk_gl_context_get_current ();
if (current &&
/* Software fallback */
- window = gdk_gl_context_get_window (gdk_gl_context_get_current ());
+ use_texture_rectangle = gdk_gl_context_use_texture_rectangle (current);
+
+ window = gdk_gl_context_get_window (current);
window_scale = gdk_window_get_scale_factor (window);
window_height = gdk_window_get_height (window);
&device_x_offset, &device_y_offset);
glGenTextures (1, &texture_id);
- glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture_id);
- glEnable (GL_TEXTURE_RECTANGLE_ARB);
+ if (use_texture_rectangle)
+ target = GL_TEXTURE_RECTANGLE_ARB;
+ else
+ target = GL_TEXTURE_2D;
+
+ glBindTexture (target, texture_id);
+ glEnable (target);
+
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
n_rects = cairo_region_num_rectangles (region);
for (i = 0; i < n_rects; i++)
glPixelStorei (GL_UNPACK_ALIGNMENT, 4);
glPixelStorei (GL_UNPACK_ROW_LENGTH, cairo_image_surface_get_stride (image)/4);
- glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 4, e.width, e.height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
+ glTexImage2D (target, 0, 4, e.width, e.height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
cairo_image_surface_get_data (image));
glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
#define FLIP_Y(_y) (window_height - (_y))
+ if (use_texture_rectangle)
+ {
+ umax = rect.width * sx;
+ vmax = rect.height * sy;
+ }
+ else
+ {
+ umax = 1.0;
+ vmax = 1.0;
+ }
+
glBegin (GL_QUADS);
- glTexCoord2f (0.0f * sx, rect.height * sy);
+ glTexCoord2f (0, vmax);
glVertex2f (rect.x * window_scale, FLIP_Y(rect.y + rect.height) * window_scale);
- glTexCoord2f (rect.width * sx, rect.height * sy);
+ glTexCoord2f (umax, vmax);
glVertex2f ((rect.x + rect.width) * window_scale, FLIP_Y(rect.y + rect.height) * window_scale);
- glTexCoord2f (rect.width * sx, 0.0f * sy);
+ glTexCoord2f (umax, 0);
glVertex2f ((rect.x + rect.width) * window_scale, FLIP_Y(rect.y) * window_scale);
- glTexCoord2f (0.0f * sx, 0.0f * sy);
+ glTexCoord2f (0, 0);
glVertex2f (rect.x * window_scale, FLIP_Y(rect.y) * window_scale);
glEnd();
}
- glDisable (GL_TEXTURE_RECTANGLE_ARB);
+ glDisable (target);
glDeleteTextures (1, &texture_id);
}
XVisualInfo *visinfo;
int i, value;
gboolean y_inverted;
- const int pixmap_attributes[] = {
- GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
- GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGBA_EXT,
+ gboolean with_alpha;
+ guint target = 0;
+ guint format = 0;
+ int pixmap_attributes[] = {
+ GLX_TEXTURE_TARGET_EXT, 0,
+ GLX_TEXTURE_FORMAT_EXT, 0,
None
};
+ with_alpha = cairo_surface_get_content (surface) == CAIRO_CONTENT_COLOR_ALPHA;
+
y_inverted = FALSE;
fbconfigs = glXGetFBConfigs (display, XScreenNumberOfScreen (screen), &nfbconfigs);
for (i = 0; i < nfbconfigs; i++)
{
visinfo = glXGetVisualFromFBConfig (display, fbconfigs[i]);
if (!visinfo || visinfo->visualid != XVisualIDFromVisual (visual))
- continue;
+ continue;
glXGetFBConfigAttrib (display, fbconfigs[i], GLX_DRAWABLE_TYPE, &value);
if (!(value & GLX_PIXMAP_BIT))
- continue;
-
- glXGetFBConfigAttrib (display, fbconfigs[i],
- GLX_BIND_TO_TEXTURE_TARGETS_EXT,
- &value);
- if ((value & GLX_TEXTURE_RECTANGLE_BIT_EXT))
- continue;
+ continue;
glXGetFBConfigAttrib (display, fbconfigs[i],
- GLX_BIND_TO_TEXTURE_RGBA_EXT,
- &value);
- if (value == FALSE)
+ GLX_BIND_TO_TEXTURE_TARGETS_EXT,
+ &value);
+ if ((value & (GLX_TEXTURE_RECTANGLE_BIT_EXT | GLX_TEXTURE_2D_BIT_EXT)) == 0)
continue;
+ if ((value & GLX_TEXTURE_2D_BIT_EXT))
+ target = GLX_TEXTURE_2D_EXT;
+ else
+ target = GLX_TEXTURE_RECTANGLE_EXT;
+
+ if (!with_alpha)
+ {
+ glXGetFBConfigAttrib (display, fbconfigs[i],
+ GLX_BIND_TO_TEXTURE_RGB_EXT,
+ &value);
+ if (!value)
+ continue;
+
+ format = GLX_TEXTURE_FORMAT_RGB_EXT;
+ }
+ else
+ {
+ glXGetFBConfigAttrib (display, fbconfigs[i],
+ GLX_BIND_TO_TEXTURE_RGBA_EXT,
+ &value);
+ if (!value)
+ continue;
+ format = GLX_TEXTURE_FORMAT_RGBA_EXT;
+ }
glXGetFBConfigAttrib (display, fbconfigs[i],
- GLX_Y_INVERTED_EXT,
- &value);
+ GLX_Y_INVERTED_EXT,
+ &value);
if (value == TRUE)
- y_inverted = TRUE;
+ y_inverted = TRUE;
break;
}
if (i == nfbconfigs)
return NULL;
+ pixmap_attributes[1] = target;
+ pixmap_attributes[3] = format;
+
glx_pixmap = g_slice_new0 (GdkGLXPixmap);
glx_pixmap->y_inverted = y_inverted;
glx_pixmap->display = display;
cairo_surface_t *surface,
cairo_region_t *region)
{
+ GdkGLContext *current;
GdkGLXPixmap *glx_pixmap;
double device_x_offset, device_y_offset;
cairo_rectangle_int_t rect;
int window_height;
int window_scale;
unsigned int texture_id;
+ gboolean use_texture_rectangle;
+ guint target;
double sx, sy;
+ float uscale, vscale;
if (cairo_surface_get_type (surface) != CAIRO_SURFACE_TYPE_XLIB)
return FALSE;
if (glx_pixmap == NULL)
return FALSE;
- window = gdk_gl_context_get_window (gdk_gl_context_get_current ())->impl_window;
+ current = gdk_gl_context_get_current ();
+
+ use_texture_rectangle = gdk_gl_context_use_texture_rectangle (current);
+
+ window = gdk_gl_context_get_window (current)->impl_window;
window_scale = gdk_window_get_scale_factor (window);
window_height = gdk_window_get_height (window);
/* Ensure all the X stuff are synced before we read it back via texture-from-pixmap */
glXWaitX();
+ if (use_texture_rectangle)
+ target = GL_TEXTURE_RECTANGLE_ARB;
+ else
+ target = GL_TEXTURE_2D;
+
glGenTextures (1, &texture_id);
- glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture_id);
- glEnable (GL_TEXTURE_RECTANGLE_ARB);
+ glBindTexture (target, texture_id);
+ glEnable (target);
+
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glXBindTexImageEXT (glx_pixmap->display, glx_pixmap->drawable,
GLX_FRONT_LEFT_EXT, NULL);
#define FLIP_Y(_y) (window_height - (_y))
+ if (use_texture_rectangle)
+ {
+ uscale = 1.0;
+ vscale = 1.0;
+ }
+ else
+ {
+ uscale = 1.0 / cairo_xlib_surface_get_width (surface);
+ vscale = 1.0 / cairo_xlib_surface_get_height (surface);
+ }
+
glBegin (GL_QUADS);
- glTexCoord2f (src_x, src_y + src_height);
+ glTexCoord2f (uscale * src_x, vscale * (src_y + src_height));
glVertex2f (rect.x * window_scale, FLIP_Y(rect.y + rect.height) * window_scale);
- glTexCoord2f (src_x + src_width, src_y + src_height);
+ glTexCoord2f (uscale * (src_x + src_width), vscale * (src_y + src_height));
glVertex2f ((rect.x + rect.width) * window_scale, FLIP_Y(rect.y + rect.height) * window_scale);
- glTexCoord2f (src_x + src_width, src_y);
+ glTexCoord2f (uscale * (src_x + src_width), vscale * src_y);
glVertex2f ((rect.x + rect.width) * window_scale, FLIP_Y(rect.y) * window_scale);
- glTexCoord2f (src_x, src_y);
+ glTexCoord2f (uscale * src_x, vscale * src_y);
glVertex2f (rect.x * window_scale, FLIP_Y(rect.y) * window_scale);
glEnd();
}
glXReleaseTexImageEXT (glx_pixmap->display, glx_pixmap->drawable,
GLX_FRONT_LEFT_EXT);
- glDisable (GL_TEXTURE_RECTANGLE_ARB);
+ glDisable (target);
glDeleteTextures (1, &texture_id);
glx_pixmap_destroy(glx_pixmap);